home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TUT09NEW.ZIP / GFX2.CPP < prev    next >
C/C++ Source or Header  |  1995-01-21  |  19KB  |  447 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. // GFX2.CPP - VGA Trainer Program secondary module containing graphics     //
  4. //            functions.  Note: This module does not follow a lot of good  //
  5. //            programming practices.  It was built to be used with the     //
  6. //            VGA tutorial series.  If you are planning on using this      //
  7. //            module with a different source file, some modifications may  //
  8. //            be necessary.                                                //
  9. //                                                                         //
  10. // Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
  11. // Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
  12. //                                                                         //
  13. // Last Modified : January 21, 1995                                        //
  14. //                                                                         //
  15. /////////////////////////////////////////////////////////////////////////////
  16.  
  17. //               //
  18. // INCLUDE FILES //
  19. //               //
  20.  
  21.   #include <alloc.h>
  22.                            // farcalloc(), farfree()
  23.   #include <dos.h>
  24.                            // geninterrupt(), FP_SEG
  25.  
  26. //         //
  27. // DEFINES //
  28. //         //
  29.  
  30.   #if !defined(PI)
  31.     #define PI 3.1415927
  32.   #endif
  33.  
  34.   #if !defined(VGA)
  35.     #define VGA 0xA000
  36.   #endif
  37.  
  38. //          //
  39. // TYPEDEFS //
  40. //          //
  41.  
  42.   typedef unsigned char byte;
  43.   typedef unsigned int  word;
  44.  
  45. //                     //
  46. // FUNCTION PROTOTYPES //
  47. //                     //
  48.  
  49.   // VIRTUAL SCREEN FUNCTIONS
  50.   void  SetUpVirtual(byte far *&Virscr, word &Vaddr);
  51.   void  ShutDown    (byte far *&Virscr);
  52.   void  Cls         (byte Col, word Where);
  53.   void  Flip        (word source, word dest);
  54.  
  55.   // MODE SETTING FUNCTIONS
  56.   void  SetMCGA     ();
  57.   void  SetText     ();
  58.  
  59.   // PALLETTE CLASS (DATA OBJECT AND RELATED FUNCTIONS)
  60.   class Pal {
  61.     public:
  62.       Pal();
  63.       void PalSet   (byte Rset, byte Gset, byte Bset);
  64.       void PalGet   (byte Col);
  65.       void PalPut   (byte Col);
  66.       void PalInc   ();
  67.       void PalDec   ();
  68.     private:
  69.       byte R;   // 0-63
  70.       byte G;   // 0-63
  71.       byte B;   // 0-63
  72.   };
  73.  
  74.   // MATH-LIKE FUNCTIONS
  75.   float rad         (float theta);
  76.   int   sgn         (int a);
  77.  
  78.   template<class T>
  79.   T abso(T value) {  if (value >= 0) return value;  else return -value; }
  80.  
  81.   // DRAWING FUNCTIONS
  82.   void  Putpixel    (word X, word Y, byte Col, word Where);
  83.   void  PutpixelVGA (word X, word Y, byte Col);
  84.   void  Line        (int a, int b, int c, int  d, int col, word Where);
  85.   void  Hline       (word X1, word X2, word Y, byte Col, word Where);
  86.  
  87.  
  88. //-------------------------VIRTUAL SCREEN FUNCTIONS------------------------//
  89.  
  90. /////////////////////////////////////////////////////////////////////////////
  91. //                                                                         //
  92. // SetUpVirtual() - This sets up the memory needed for a virtual screen.   //
  93. //                                                                         //
  94. /////////////////////////////////////////////////////////////////////////////
  95.  
  96. void SetUpVirtual(byte far *&Virscr, word &Vaddr) {
  97.   Virscr = (byte far *) farcalloc(64000,1);
  98.   Vaddr = FP_SEG(Virscr);
  99. }
  100.  
  101. /////////////////////////////////////////////////////////////////////////////
  102. //                                                                         //
  103. // ShutDown() - This frees the memory used by a virtual screen.            //
  104. //                                                                         //
  105. /////////////////////////////////////////////////////////////////////////////
  106.  
  107. void ShutDown(byte far *&Virscr) {
  108.   farfree(Virscr);
  109. }
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112. //                                                                         //
  113. // Cls() - This clears the screen at Where to color Col.                   //
  114. //                                                                         //
  115. /////////////////////////////////////////////////////////////////////////////
  116.  
  117. void Cls(byte Col, word Where) {
  118.   asm {
  119.     push    es           // save ES
  120.     mov     cx, 32000    // this is our loop counter.  we want to clear
  121.                          //   64000 bytes of memory, so why do we use 32000?
  122.                          //   1 word = 2 bytes, and we are moving a word at
  123.                          //   a time
  124.     mov     es, [Where]  // move address in Where to ES
  125.     xor     di, di       // zero out DI
  126.     mov     al, [Col]    // move color to AL
  127.     mov     ah, al       // move color to AH (Remember, will be moving
  128.                          //   a WORDS, so we need two copies
  129.     rep     stosw        // copy AX to Where and drecrement CX by 1
  130.                          //   until CX equals 0
  131.     pop     es           // restore ES
  132.   }
  133. }
  134.  
  135. /////////////////////////////////////////////////////////////////////////////
  136. //                                                                         //
  137. // Flip() - This copies 64000 bytes from "source" to "destination".        //
  138. //                                                                         //
  139. /////////////////////////////////////////////////////////////////////////////
  140.  
  141. void Flip(word source, word dest) {
  142.   asm {
  143.     push    ds           // save DS
  144.     mov     ax, [dest]   // copy segment of destination to AX
  145.     mov     es, ax       // set ES to point to destination
  146.     mov     ax, [source] // copy segment of source to AX
  147.     mov     ds, ax       // set DS to point to source
  148.     xor     si, si       // zero out SI
  149.     xor     di, di       // zero out DI
  150.     mov     cx, 32000    // set our counter to 32000
  151.     rep     movsw        // move source to destination by words.  decrement
  152.                          //   CX by 1 each time until CX is 0
  153.     pop     ds           // restore DS
  154.   }
  155. }
  156.  
  157.  
  158. //--------------------------MODE SETTING FUNCTIONS-------------------------//
  159.  
  160. /////////////////////////////////////////////////////////////////////////////
  161. //                                                                         //
  162. // SetMCGA() - This function gets you into 320x200x256 mode.               //
  163. //                                                                         //
  164. /////////////////////////////////////////////////////////////////////////////
  165.  
  166. void SetMCGA() {
  167.   _AX = 0x0013;
  168.   geninterrupt (0x10);
  169. }
  170.  
  171. /////////////////////////////////////////////////////////////////////////////
  172. //                                                                         //
  173. // SetText() - This function gets you into text mode.                      //
  174. //                                                                         //
  175. /////////////////////////////////////////////////////////////////////////////
  176.  
  177. void SetText() {
  178.   _AX = 0x0003;
  179.   geninterrupt (0x10);
  180. }
  181.  
  182.  
  183. //----------------------------PALLETTE FUNCTIONS---------------------------//
  184.  
  185. /////////////////////////////////////////////////////////////////////////////
  186. //                                                                         //
  187. // Pal() - This constructor initializes all Pal variables (R, G, and B) to //
  188. //         zero.  This ensures that all Pal objects start in a consistent  //
  189. //         state.                                                          //
  190. //                                                                         //
  191. /////////////////////////////////////////////////////////////////////////////
  192.  
  193. Pal::Pal() { R = B = G = 0; }
  194.  
  195. /////////////////////////////////////////////////////////////////////////////
  196. //                                                                         //
  197. // PalSet() - This sets the Red, Green, and Blue values of a given color.  //
  198. //            Set invalid colors ( >63 ) equal to 0.                       //
  199. //                                                                         //
  200. /////////////////////////////////////////////////////////////////////////////
  201.  
  202. void Pal::PalSet(byte Rset, byte Gset, byte Bset) {
  203.  
  204.    R = (Rset < 64) ? Rset : 0;
  205.    G = (Gset < 64) ? Gset : 0;
  206.    B = (Bset < 64) ? Bset : 0;
  207.  
  208. }
  209.  
  210. /////////////////////////////////////////////////////////////////////////////
  211. //                                                                         //
  212. // PalGet() - This reads the values of the Red, Green, and Blue values of  //
  213. //            a certain color.                                             //
  214. //                                                                         //
  215. /////////////////////////////////////////////////////////////////////////////
  216.  
  217. void Pal::PalGet(byte Col) {
  218.  
  219.   byte Rtemp, Gtemp, Btemp;
  220.  
  221.   asm {
  222.     mov     dx, 0x03C7   // load DX with 3C7 (read pallette function)
  223.     mov     al, [Col]    // move color to AL
  224.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  225.                          //   work with the color in AL
  226.     add     dx, 2        // load DX with 3C9 (read RGB colors)
  227.     in      al, dx       // read Red   to AL
  228.     mov     [Rtemp],al   // copy AL to rr
  229.     in      al, dx       // read Green to AL
  230.     mov     [Gtemp],al   // copy AL to gg
  231.     in      al, dx       // read Blue  to AL
  232.     mov     [Btemp],al   // copy AL to bb
  233.   }
  234.  
  235.   R = Rtemp;
  236.   G = Gtemp;
  237.   B = Btemp;
  238.  
  239. }
  240.  
  241. /////////////////////////////////////////////////////////////////////////////
  242. //                                                                         //
  243. // PalPut() - This sets the Red, Green, and Blue values of a color.        //
  244. //                                                                         //
  245. /////////////////////////////////////////////////////////////////////////////
  246.  
  247. void Pal::PalPut (byte Col) {
  248.  
  249.   byte Rtemp = R, Gtemp = G, Btemp = B;
  250.  
  251.   asm {
  252.     mov     dx, 0x3C8    // load DX with 3C8 (write pallette function)
  253.     mov     al, [Col]    // move color to AL
  254.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  255.                          //   work with the color in AL
  256.     inc     dx           // load DX with 3C9 (write RGB colors)
  257.     mov     al, [Rtemp]  // move Red   to AL
  258.     out     dx, al       // write DX to VGA (tell VGA that we want to use
  259.                          //   the Red value in AL
  260.     mov     al, [Gtemp]  // move Green to AL
  261.     out     dx, al       // write DX to VGA
  262.     mov     al, [Btemp]  // move Blue  to AL
  263.     out     dx, al       // write DX to VGA
  264.   }
  265. }
  266.  
  267. /////////////////////////////////////////////////////////////////////////////
  268. //                                                                         //
  269. // PalInc() - This increments the R, G, and B values of a given Pal        //
  270. //            variable, keeping all values less than 64.                   //
  271. //                                                                         //
  272. /////////////////////////////////////////////////////////////////////////////
  273.  
  274. void Pal::PalInc() {
  275.  
  276.   // if (R < 63) R = R + 1; else R = 63;
  277.   R = (R < 63) ? (R + 1) : 63;
  278.   G = (G < 63) ? (G + 1) : 63;
  279.   B = (B < 63) ? (B + 1) : 63;
  280.  
  281. }
  282.  
  283. /////////////////////////////////////////////////////////////////////////////
  284. //                                                                         //
  285. // PalDec() - This decrements the R, G, and B values of a given Pal        //
  286. //            variable, keeping all values greater than or equal to zero.  //
  287. //                                                                         //
  288. /////////////////////////////////////////////////////////////////////////////
  289.  
  290. void Pal::PalDec() {
  291.  
  292.   // if (R > 0) R = R - 1; else R = 0;
  293.   R = (R > 0) ? (R - 1) : 0;
  294.   G = (G > 0) ? (G - 1) : 0;
  295.   B = (B > 0) ? (B - 1) : 0;
  296.  
  297. }
  298.  
  299.  
  300. //----------------------------MATH-LIKE FUNCTIONS--------------------------//
  301.  
  302. /////////////////////////////////////////////////////////////////////////////
  303. //                                                                         //
  304. // rad() - This calculates the degrees of an angle.                        //
  305. //                                                                         //
  306. /////////////////////////////////////////////////////////////////////////////
  307.  
  308. float rad(float theta) {
  309.   return ((theta * PI)/180);
  310. }
  311.  
  312. /////////////////////////////////////////////////////////////////////////////
  313. //                                                                         //
  314. // sgn() - This checks the sign of an integer and returns a 1, -1, or 0.   //
  315. //                                                                         //
  316. /////////////////////////////////////////////////////////////////////////////
  317.  
  318. int sgn (int a) {
  319.  
  320.   if (a > 0)  return +1;
  321.   if (a < 0)  return -1;
  322.   return 0;
  323. }
  324.  
  325.  
  326. //-----------------------------DRAWING FUNCTIONS---------------------------//
  327.  
  328. /////////////////////////////////////////////////////////////////////////////
  329. //                                                                         //
  330. // Putpixel() - This puts a pixel on the screen by writing directly to     //
  331. //              memory.                                                    //
  332. //                                                                         //
  333. /////////////////////////////////////////////////////////////////////////////
  334.  
  335. void Putpixel (word X, word Y, byte Col, word Where) {
  336.   asm {
  337.     mov     ax, [Where]  // move segment of Where to AX
  338.     mov     es, ax       // ES = VGA
  339.     mov     bx, [X]      // BX = X
  340.     mov     dx, [Y]      // DX = Y
  341.     mov     ah, dl       // AH = Y*256
  342.     xor     al, al       // AX = Y*256
  343.     shl     dx, 6        // DX = Y*64
  344.     add     dx, ax       // DX = Y*320
  345.     add     bx, dx       // BX = Y*320 + X
  346.     mov     ah, [Col]    // move value of Col into AH
  347.     mov     byte ptr es:[bx], ah  // move Col to the offset in memory (DI)
  348.   }
  349. }
  350.  
  351. /////////////////////////////////////////////////////////////////////////////
  352. //                                                                         //
  353. // PutpixelVGA() - This puts a pixel on the screen by writing directly to  //
  354. //                 VGA memory.                                             //
  355. //                                                                         //
  356. /////////////////////////////////////////////////////////////////////////////
  357.  
  358. void PutpixelVGA (word X, word Y, byte Col) {
  359.   asm {
  360.     mov     ax, 0xA000   // AX = VGA Segment
  361.     mov     es, ax       // ES = VGA Segment
  362.     mov     bx, [X]      // BX = X
  363.     mov     dx, [Y]      // DX = Y
  364.     mov     ah, dl       // AX = Y*256 (AL is already 0 from A000 address)
  365.     shl     dx, 6        // DX = Y*64
  366.     add     dx, ax       // DX = Y*320
  367.     add     bx, dx       // BX = Y*320 + X
  368.     mov     ah, [Col]    // move value of Col into AH
  369.     mov     byte ptr es:[bx], ah  // move Col to the offset in memory (DI)
  370.   }
  371. }
  372.  
  373. /////////////////////////////////////////////////////////////////////////////
  374. //                                                                         //
  375. // Line() - This draws a line from a,b to c,d of color col on screne Where //
  376. //                                                                         //
  377. /////////////////////////////////////////////////////////////////////////////
  378.  
  379. void Line(int a, int b, int c, int d, int col, word Where) {
  380.  
  381.   int i,u,s,v,d1x,d1y,d2x,d2y,m,n;
  382.  
  383.   u   = c-a;       // x2-x1
  384.   v   = d-b;       // y2-y1
  385.   d1x = sgn(u);    // d1x is the sign of u (x2-x1) (VALUE -1,0,1)
  386.   d1y = sgn(v);    // d1y is the sign of v (y2-y1) (VALUE -1,0,1)
  387.   d2x = sgn(u);    // d2x is the sign of u (x2-x1) (VALUE -1,0,1)
  388.   d2y = 0;
  389.   m   = abso(u);   // m is the distance between x1 and x2
  390.   n   = abso(v);   // n is the distance between y1 and y2
  391.  
  392.   if (m<=n) {      // if the x distance is greater than the y distance
  393.     d2x = 0;
  394.     d2y = sgn(v);  // d2y is the sign of v (x2-x1) (VALUE -1,0,1)
  395.     m   = abso(v); // m is the distance between y1 and y2
  396.     n   = abso(u); // n is the distance between x1 and x2
  397.   }
  398.  
  399.   s = m / 2; // s is the m distance (either x or y) divided by 2
  400.  
  401.   for (i=0;i<m+1;i++) { // repeat this loop until it
  402.                  // is = to m (y or x distance)
  403.     Putpixel(a,b,col,Where); // plot a pixel at the original x1, y1
  404.     s += n;                  // add n (dis of x or y) to s (dis of x of y)
  405.     if (s >= m) {            // if s is >= m (distance between y1 and y2)
  406.       s -= m;
  407.       a += d1x;
  408.       b += d1y;
  409.     }
  410.     else {
  411.       a += d2x;
  412.       b += d2y;
  413.     }
  414.   }
  415.  
  416. }
  417.  
  418. /////////////////////////////////////////////////////////////////////////////
  419. //                                                                         //
  420. // Hline() - This draws a horizontal line from X1 to X2 on line Y in color //
  421. //           Col at memory location Where.                                 //
  422. //                                                                         //
  423. /////////////////////////////////////////////////////////////////////////////
  424.  
  425. void Hline (word X1, word X2, word Y, byte Col, word Where) {
  426.   asm {
  427.     mov     ax, [Where]  // move segment of Where to AX
  428.     mov     es, ax       // set ES to segment of Where
  429.     mov     ax, [Y]      // set AX to Y
  430.     mov     di, ax       // set DI to Y
  431.     shl     ax, 8        // shift AX left 8 places (multiply Y by 256)
  432.     shl     di, 6        // shift DI left 6 places (multiply Y by 64)
  433.     add     di, ax       // add AX to DI (Y*64 + Y*256 = Y*320)
  434.     add     di, [X1]     // add the X1 offset to DI
  435.     mov     al, [Col]    // move Col to AL
  436.     mov     ah, al       // move Col to AH (we want 2 copies for word moving)
  437.     mov     cx, [X2]     // move X2 to CX
  438.     sub     cx, [X1]     // move the change in X to CX
  439.     shr     cx, 1        // divide change in X by 2 (for word moving)
  440.     jnc     Start        // if we have an even number of moves, go to Start
  441.     stosb                // otherwise, move one byte more
  442.   }
  443.   Start: asm {
  444.     rep     stosw        // do it!
  445.   }
  446. }
  447.